/****

 activequant - activestocks.eu

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along
 with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

 
 contact  : contact@activestocks.eu
 homepage : http://www.activestocks.eu

 ****/
package org.activequant.data.retrieval.ib;

import org.activequant.core.domainmodel.InstrumentSpecification;
import org.activequant.core.domainmodel.SeriesSpecification;
import org.activequant.core.domainmodel.data.Candle;
import org.activequant.core.types.TimeFrame;
import org.activequant.data.annotations.Vendor;
import org.activequant.data.retrieval.ICandleSubscriptionSource;
import org.activequant.data.retrieval.SubscriptionSourceBase;
import org.activequant.util.ib.IBTwsConnection;
import org.activequant.util.pattern.events.IEventListener;
import org.apache.log4j.Logger;

/**
 * 
 * abstracted Interactive Broker Candle series source for real-time candle feed from IB requires a properly configured monitor. <br/>
 * IBCandleSource extends SubscriptionSourceBase&lt;Candle&gt; implements ICandleSubscriptionSource.<br>
 * Holds the following associated variables:
 * <ul>
 * <li>connection(IBTwsConnection)</li>
 * </ul>
 * Holds the following inherited variables:
 * <ul>
 * <li>activeBackends(Map&lt;Topic, Subscription&gt;)</li>
 * <li>activeSubscriptions(Queue&lt;SubscriptionDelegate&gt;)</li>
 * </ul>
 * <b>History:</b><br>
 *  - [19.08.2008] Created (Ulrich Staudinger)<br>
 *  
 *  @author Ulrich Staudinger
 *  
 */
@Vendor("IB")
public class IBCandleSource extends SubscriptionSourceBase<Candle> implements ICandleSubscriptionSource {
	/**
	 * public static final String TRADES = "TRADES";
	 */
	public static final String TRADES = "TRADES";
	/**
	 * public static final String MIDPOINT = "MIDPOINT";
	 */
	public static final String MIDPOINT = "MIDPOINT";
	/**
	 * public static final String BIDASK = "BIDASK";
	 */
	public static final String BIDASK = "BID_ASK";
	

	public static final String DATA_TYPE = "type";
	/**
	 * private IBTwsConnection connection;
	 */
	private IBTwsConnection connection;

	protected final static Logger log = Logger.getLogger(IBCandleSource.class);
	/**
	 * constructs a IBCandleSource(extends SubscriptionSourceBase&lt;Candle&gt; implements ICandleSubscriptionSource) using the given monitor(IBTwsConnection)
	 * to set its associated connection(IBTwsConnection)
	 * @param monitor
	 */
	public IBCandleSource(IBTwsConnection monitor) {
		this.connection = monitor;
	}
	/**
	 * CandleSubscription extends Subscription. Holds the following associated variables:
	 * <ul>
	 * <li>spec(SeriesSpecification)</li>
	 * <li>listener(IEventListener&lt;Candle&gt;)</li>
	 * </ul>
	 * Holds the following inherited variables:
	 * <ul>
	 * <li>isActive(AtomicBoolean)</li>
	 * <li>refCount(AtomicInteger)</li>
	 * <li>instrument(InstrumentSpecification)</li>
	 * <li>event(Event&lt;Candle&gt;)</li>
	 * </ul>
	 * @author Dimitar
	 *
	 */
	private class CandleSubscription extends Subscription {
		/**
		 * private final SeriesSpecification spec;
		 */
		private final SeriesSpecification spec; 
		/**
		 * constructs a CandleSubscription(extends Subscription) using the given s(SeriesSpecification) to set its associated spec(SeriesSpecification)
		 * @param s
		 */
		CandleSubscription(SeriesSpecification s) {
			spec = s;
		}
		/**
		 * private final IEventListener&lt;Candle&gt; listener = new IEventListener&lt;Candle&gt;() {...}<br/>
		 * A listener that re-fires any event(Candle)
		 */
		private final IEventListener<Candle> listener = new IEventListener<Candle>() {
			public void eventFired(Candle event) {
				fireEvent(event);
			}
		};
		/**
		 * Subscribes the associated listener(IEventListener&lt;Candle&gt;) for real time bars from the connection(IBTwsConnection) for the associated spec(SeriesSpecification)
		 */
		@Override
		protected void handleActivate() {
			connection.subscribeToCandleStream(listener, spec);
		}
		/**
		 * Unsubscribes the associated listener(IEventListener&lt;Candle&gt;) from listening to real time bars from the connection(IBTwsConnection) for the associated spec(SeriesSpecification)
		 */
		@Override
		protected void handleCancel() {
			connection.unsubscribeFromCandleStream(listener, spec);
		}
	}
	
	/**
	 * <strong>1.</strong> Creates a spec(SeriesSpecification) using the given arg0(InstrumentSpecification) and arg1(TimeFrame) to set its associated instrumentSpecification(InstrumentSpecification) and timeFrame(TimeFrame)<br/>
	 * <strong>2.</strong> Creates and returns a CandleSubscription(extends Subscription) using that spec(SeriesSpecification) to set its associated spec(SeriesSpecification)
	 */
	@Override
	protected Subscription createSubscription(InstrumentSpecification arg0, TimeFrame arg1) {
		SeriesSpecification spec = new SeriesSpecification(arg0, arg1);
		return new CandleSubscription(spec);
	}

}
